[小ネタ]全リージョンで未確認のSNSサブスクリプションを洗い出す
最近よく以下の記事からGuardDutyの検知結果をメール通知させるために、SNSトピックを全リージョンに展開することが多いのですが、メールのサブスクリプション承認作業で一部のリージョンが漏れていたことがありました。
そんなときに全リージョンで未確認のサブスクリプションを洗い出すコマンドを書いたので、小ネタとして置いておきます。
全リージョンにメール通知用SNSトピックを用意しないといけないときの確認作業にご利用ください。
前提
- jqコマンドが利用できること
- EC2 describe-regions、SNS list-subscriptionsの権限があること
作成したコマンド
早速ですが、本題のコマンドです。全リージョンに対して未確認となっているサブスクリプションを取得して、あればSNSトピックのArnを表示するような形にしています。
for r in `aws ec2 describe-regions --query 'Regions[*]'.RegionName --output text` do echo $r result=`aws sns list-subscriptions --region $r | jq '[.Subscriptions[]]' | jq 'map(select( .SubscriptionArn == "PendingConfirmation" ))'` if [ "$result" != '[]' ] ; then echo $result | jq '.[].TopicArn' fi done
上記のコマンドはCloudShellから実行するのが簡単なのでおすすめです。
実行結果
eu-north-1 ap-south-1 eu-west-3 eu-west-2 eu-west-1 ap-northeast-3 ap-northeast-2 ap-northeast-1 "arn:aws:sns:ap-northeast-1:111111111111:test-topic" "arn:aws:sns:ap-northeast-1:111111111111:test-topic" sa-east-1 ca-central-1 ap-southeast-1 ap-southeast-2 eu-central-1 us-east-1 "arn:aws:sns:us-east-1:111111111111:test-topic" us-east-2 us-west-1 us-west-2
実行してみると、処理中のリージョンが表示されて未確認となっているサブスクリプションがあるとSNSトピックのArnが表示されます。このとき同じトピックに複数未確認のサブスクリプションがあっても表示されるようになっています。
全リージョンに未確認のサブスクリプションがなければ、リージョン名のみが表示されるだけとなります。
コマンドの詳細
あまり説明するところもありませんが、一応コマンドの説明。
for r in `aws ec2 describe-regions --query 'Regions[*]'.RegionName --output text`
1行目では、オプトインの全リージョンを取得して変数r
に格納して、for文で回しています。この形式は全リージョンで同じコマンドを実行したい時の定番なので是非活用してみてください。
result=`aws sns list-subscriptions --region $r | jq '[.Subscriptions[]]' | jq 'map(select( .SubscriptionArn == "PendingConfirmation" ))'`
4行目で未確認となっているサブスクリプションを取得して変数result
に格納しています。未確認のサブスクリプションはSubscriptionArn
の値がPendingConfirmation
となるため、この条件に一致したものをmapで詰め直しています。
if [ "$result" != '[]' ] ; then echo $result | jq '.[].TopicArn' fi
5~7行名は未確認のサブスクリプションが存在していた場合にトピックのArnを表示しています。逆に未確認のサブスクリプションがない場合(空のリスト)のときは処理しないようif文にしています。
まとめ
GuardDutyやSecurityHubなど、全リージョンに展開してSNSのサブスクリプション承認をしなければならない時にお役立てください。こういった全リージョン確認する作業はできるだけコンソールではなくCLIから確認できるようにしたいですね。